package record

import (
	"context"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"goproject/commonType"
	ctrl "sigs.k8s.io/controller-runtime"
)

var log = ctrl.Log.WithName("mongodb/record")

/*
Record 执行记录：测试任务每执行一侧生成一个

	{
	  id: '1',
	  task_id: '1',
	  executor: '粥隔离',
	  start_time: '2023-09-28 01:01:01',
	  end_time: '2023-09-28 02:01:01',
	  status: 2,
	  // 1 进行中 2 执行成功 3 执行失败
	}
*/

type Store struct {
	collection *mongo.Collection
}

func NewStore(db *mongo.Database) *Store {
	return &Store{
		collection: db.Collection("record"),
	}
}

// Create 执行记录
func (s *Store) Create(ctx context.Context, record commonType.Record) (commonType.Record, error) {
	result, err := s.collection.InsertOne(ctx, record)
	if err != nil {
		log.Error(err, "create record failed", "record", record)
		return commonType.Record{}, err
	}
	objectID := result.InsertedID.(primitive.ObjectID)
	record.ID = &objectID
	return record, nil
}

// Get 获取执行记录
func (s *Store) Get(ctx context.Context, id primitive.ObjectID) (commonType.Record, error) {
	var record commonType.Record
	err := s.collection.FindOne(ctx, primitive.M{"_id": id}).Decode(&record)
	if err != nil {
		log.Error(err, "get record failed", "id", id)
		return commonType.Record{}, err
	}
	return record, err
}

// GetAll 获取所有执行记录
func (s *Store) GetAll(ctx context.Context) ([]commonType.Record, error) {
	var records []commonType.Record
	cursor, err := s.collection.Find(ctx, primitive.M{})
	if err != nil {
		return nil, err
	}
	defer cursor.Close(ctx)

	for cursor.Next(ctx) {
		var record commonType.Record
		err := cursor.Decode(&record)
		if err != nil {
			return nil, err
		}
		records = append(records, record) // 追加解码后的记录到 records 切片
	}

	if err := cursor.Err(); err != nil {
		return nil, err
	}

	return records, nil
}

func (s *Store) GetByTaskID(ctx context.Context, id primitive.ObjectID, skip int, pageSize int) ([]commonType.Record, error) {
	var records []commonType.Record
	findOptions := options.Find()
	findOptions.SetSkip(int64(skip))
	findOptions.SetLimit(int64(pageSize))
	cursor, err := s.collection.Find(ctx, primitive.M{"task_id": id}, findOptions)
	if err != nil {
		log.Error(err, "get record failed, find failed", "id", id)
		return nil, err
	}
	defer cursor.Close(ctx)
	for cursor.Next(ctx) {
		var record commonType.Record
		err := cursor.Decode(&record)
		if err != nil {
			log.Error(err, "get record failed, decode failed", "id", id)
			return nil, err
		}
		records = append(records, record)
	}
	return records, err
}

// ListByTaskID 由任务ID，获取执行记录列表
func (s *Store) ListByTaskID(ctx context.Context, taskID primitive.ObjectID) ([]commonType.Record, error) {
	var records []commonType.Record
	cursor, err := s.collection.Find(ctx, primitive.M{"task_id": taskID})
	if err != nil {
		log.Error(err, "list record failed, find failed", "taskID", taskID)
		return nil, err
	}
	err = cursor.All(ctx, &records)
	if err != nil {
		log.Error(err, "list record failed, decode failed", "taskID", taskID)
		return nil, err
	}
	return records, err
}

// List 获取执行记录列表
func (s *Store) List(ctx context.Context) ([]commonType.Record, error) {
	var records []commonType.Record
	cursor, err := s.collection.Find(ctx, primitive.M{})
	if err != nil {
		log.Error(err, "list record failed, find failed")
		return nil, err
	}
	err = cursor.All(ctx, &records)
	if err != nil {
		log.Error(err, "list record failed, decode failed")
		return nil, err
	}
	return records, err
}

// Update 更新执行记录
func (s *Store) Update(ctx context.Context, record commonType.Record) error {
	_, err := s.collection.UpdateOne(ctx, primitive.M{"_id": record.ID}, primitive.M{"$set": record})
	if err != nil {
		log.Error(err, "update record failed", "record", record)
		return err
	}
	return nil
}

// Delete 删除执行记录
func (s *Store) Delete(ctx context.Context, id primitive.ObjectID) error {
	_, err := s.collection.DeleteOne(ctx, primitive.M{"_id": id})
	if err != nil {
		log.Error(err, "delete record failed", "id", id)
		return err
	}
	return nil
}

// DeleteAll 删除所有执行记录
func (s *Store) DeleteAll(ctx context.Context) error {
	_, err := s.collection.DeleteMany(ctx, primitive.M{})
	if err != nil {
		log.Error(err, "delete all record failed")
		return err
	}
	return nil
}
